home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / x68000.arc / SOURCE.ARC / SYMBOLTA.MOD < prev    next >
Encoding:
Modula Implementation  |  1985-12-03  |  4.4 KB  |  174 lines

  1. IMPLEMENTATION MODULE SymbolTable;
  2. (* Initializes symbol table.  Maintains list of all labels, *)
  3. (* along with their values.  Provides access to the list.   *)
  4.  
  5.    FROM LongNumbers IMPORT
  6.       LONG, LongClear;
  7.  
  8.    FROM Parser IMPORT
  9.       TOKEN;
  10.  
  11.    FROM Strings IMPORT
  12.       CompareStr;
  13.  
  14.  
  15.    CONST
  16.       MAXSYM = 500;   (* Maximum entries in Symbol Table *)
  17.  
  18.  
  19.    TYPE
  20.       SYMBOL = RECORD
  21.                   Name : TOKEN;
  22.                   Value : LONG;
  23.                END;
  24.  
  25.    VAR
  26.       SymTab : ARRAY [1..MAXSYM] OF SYMBOL;
  27.       Next : CARDINAL;   (* Array index into next entry in Symbol Table *)
  28.       Top : INTEGER;   (* Last used array position as seen by Sort *)
  29.  
  30.  
  31.  
  32.    PROCEDURE FillSymTab (Label : TOKEN; Value : LONG; VAR Full : BOOLEAN);
  33.    (* Add a symbol to the table *)
  34.       BEGIN
  35.          IF Next <= MAXSYM THEN
  36.             SymTab[Next].Name := Label;
  37.             SymTab[Next].Value := Value;
  38.             INC (Next);
  39.             Full := FALSE;
  40.          ELSE
  41.             Full := TRUE;
  42.          END;
  43.       END FillSymTab;
  44.  
  45.  
  46.  
  47.    PROCEDURE SortSymTab (VAR NumSyms : CARDINAL);
  48.    (* Sort symbols into alphabetical order *)
  49.  
  50.       VAR
  51.          i, j, gap : INTEGER;   (* Shell Sort causes j to go negative *)
  52.          Temp : SYMBOL;
  53.  
  54.       PROCEDURE Swap;
  55.          BEGIN
  56.             Temp := SymTab[j];
  57.             SymTab[j] := SymTab[j + gap];
  58.             SymTab[j + gap] := Temp;
  59.          END Swap;
  60.  
  61.       BEGIN   (* Sort *)
  62.          Top := Next - 1;
  63.  
  64.          gap := (Top + 1) DIV 2;
  65.          WHILE gap > 0 DO
  66.             i := gap;
  67.             WHILE i <= Top DO
  68.                j := i - gap;
  69.                WHILE j >= 1 DO
  70.                   IF CompareStr (SymTab[j].Name, SymTab[j + gap].Name) > 0 THEN
  71.                      Swap;
  72.                   END;
  73.                   j := j - gap;
  74.                END;
  75.                INC (i);
  76.             END;
  77.             gap := gap DIV 2;
  78.          END;
  79.  
  80.          NumSyms := Top;
  81.       END SortSymTab;
  82.  
  83.  
  84.  
  85.    PROCEDURE ReadSymTab (LABEL : ARRAY OF CHAR; 
  86.                          VAR Value : LONG; VAR Duplicate : BOOLEAN) : BOOLEAN;
  87.    (* Passes Value of Label to calling program -- returns FALSE if the *)
  88.    (* Label is not defined.  Also checks for Multiply Defined Symbols  *)
  89.  
  90.       CONST
  91.          GoLower = -1;
  92.          GoHigher = +1;
  93.  
  94.       VAR
  95.          i, j, mid : INTEGER;
  96.          Search : INTEGER;
  97.          Found : BOOLEAN;
  98.          c : CHAR;
  99.          Label : TOKEN;         
  100.  
  101.       BEGIN
  102.          LongClear (Value);
  103.          Duplicate := FALSE;
  104.  
  105.          i := 0;
  106.          REPEAT
  107.             c := LABEL[i];
  108.             Label[i] := c;
  109.             INC (i);
  110.          UNTIL (c = 0C) OR (i > 8);
  111.  
  112.          IF c # 0C THEN   (* Operand label too long --> Undefined *)
  113.             RETURN FALSE;
  114.          END;
  115.  
  116.          i := 1;
  117.          j := Top;
  118.          Found := FALSE;
  119.  
  120.          REPEAT   (* Binary search *)
  121.             mid := (i + j) DIV 2;
  122.             Search := CompareStr (Label, SymTab[mid].Name);
  123.  
  124.             IF Search = GoLower THEN
  125.                j := mid - 1;
  126.             ELSIF Search = GoHigher THEN
  127.                i := mid + 1;
  128.             ELSE   (* Got It! *)
  129.                Found := TRUE;
  130.             END;
  131.          UNTIL (j < i) OR Found;
  132.  
  133.          IF Found THEN
  134.             IF mid > 1 THEN
  135.                IF CompareStr (SymTab[mid].Name, SymTab[mid - 1].Name) = 0 THEN
  136.                   Duplicate := TRUE;   (* Multiply Defined Symbol *)
  137.                END;
  138.             END;
  139.             IF mid < Top THEN
  140.                IF CompareStr (SymTab[mid].Name, SymTab[mid + 1].Name) = 0 THEN
  141.                   Duplicate := TRUE;   (* Multiply Defined Symbol *)
  142.                END;
  143.             END;
  144.  
  145.             Value := SymTab[mid].Value;
  146.             RETURN TRUE;
  147.          ELSE
  148.             RETURN FALSE;
  149.          END;
  150.       END ReadSymTab;
  151.  
  152.  
  153.  
  154.    PROCEDURE ListSymTab (i : CARDINAL; VAR Label : TOKEN; VAR Value : LONG);
  155.    (* Returns the i-th item in the symbol table *)
  156.       BEGIN
  157.          IF i < Next THEN
  158.             Label := SymTab[i].Name;
  159.             Value := SymTab[i].Value;
  160.          END;
  161.       END ListSymTab;
  162.       
  163.  
  164.  
  165. BEGIN   (* MODULE Initialization *)
  166.    FOR Next := 1 TO MAXSYM DO
  167.       SymTab[Next].Name := "";
  168.       LongClear (SymTab[Next].Value);
  169.    END;
  170.  
  171.    Top := 0;
  172.    Next := 1;
  173. END SymbolTable.
  174.